// 按位运算

#include <stdio.h>

int main(int argc, char const *argv[])
{
    // 按位运算符
    // &: 按位的与
    // |: 按位的或
    // ~: 按位取反
    // ^: 按位的异或
    // <<: 左移
    // >>: 右移
    
    printf("0101 1010 AND 1000 1100: %x\n", 0b01011010 & 0b10001100);
    printf("0xFE AND 1000 1100: %x\n", 0xFE & 0b10001100);

    printf("10101010 OR 1 0101 0100 = %x\n", 0b10101010 | 0b101010100);
    printf("0100 OR 1111 = %x\n", 0b0100 | 0b1111);

    printf("NOT 0xFFFF = %x\n", ~0xFFFF);

    unsigned char c = 0xAA;
    printf(" c = %hhx\n", c);
    // 取反
    printf("~c = %hhx\n", (char)~c);
    // 补码
    printf("-c = %hhx\n", (char)-c);

    // 逻辑运算：不是0就使1
    printf("%d\n", !100);

    // 异或：加密
    printf("FFFF XOR FFFF = %x\n", 0xFFFF ^ 0xFFFF);

    // 左移: i << j
    // i 中所有位向左移动 j 个位置, 右边填入 0
    // 所有小于 int 的类型, 移位以 int 的方式做, 结果是 int
    // x << n => x * 2^n
    printf("5 << 3 = %d\n", 5 << 3);
    printf("c << 4 = %x\n", c << 4);
    // 右移类似
    int a = 0x80000000;
    unsigned int b = 0x80000000;
    printf("a = %d\n", a);
    printf("b = %u\n", b);
    printf("a >> 1 = %d\n", a >> 1);
    printf("b >> 1 = %d\n", b >> 1);
    printf("a << 1 = %d\n", a << 1);
    printf("b << 1 = %d\n", b << 1);
    // 右移要判断符号, 左移不管
    // 不要移负数位
    
    return 0;
}